package main

import (
	"fmt"
	"log"
	"time"

	"gitee.com/barryzxy/gomodbus"
)

func main() {
	fmt.Println("=== 网关协议读参数功能演示 ===")

	// 启动服务器
	go startServer()

	// 等待服务器启动
	time.Sleep(2 * time.Second)

	// 运行客户端测试
	runReadParamsDemo()
}

// startServer 启动测试服务器
func startServer() {
	fmt.Println("正在启动测试服务器...")

	// 创建TCP服务器
	server := gomodbus.NewTCPServer("127.0.0.1:5022", 5*time.Second)
	if server == nil {
		log.Fatal("创建服务器失败")
	}

	// 创建网关设备节点
	gatewayNode := gomodbus.NewNodeRegister(65, 0, 10, 0, 10, 0, 10, 0, 10)
	gatewayNode.InitGatewayDataStore(100)

	// 创建变送器设备节点
	transmitterNode := gomodbus.NewNodeRegister(1, 0, 10, 0, 10, 0, 10, 0, 10)
	transmitterNode.InitGatewayDataStore(100)

	// 设置一些初始参数值用于测试
	gatewayStore := gatewayNode.GetGatewayDataStore()
	gatewayStore.SetGatewayParam(gomodbus.GatewayParamRS485Baudrate, 115200)
	gatewayStore.SetGatewayParam(gomodbus.GatewayParamRS485Address, 65)
	gatewayStore.SetGatewayParam(gomodbus.GatewayParamBacklightTime, 2)

	transmitterStore := transmitterNode.GetGatewayDataStore()
	transmitterStore.SetSubDevParam(gomodbus.SubDevParamPressureUnit, gomodbus.PressureUnitKPa)
	transmitterStore.SetSubDevParam(gomodbus.SubDevParamDataReportInterval, 60)
	transmitterStore.SetSubDevParam(gomodbus.SubDevParamTransmitterAddr, 1)

	// 添加节点到服务器
	server.AddNodes(gatewayNode, transmitterNode)

	// 启动服务器
	err := server.ListenAndServe()
	if err != nil {
		log.Printf("启动服务器失败: %v", err)
		return
	}

	fmt.Println("测试服务器已启动 (127.0.0.1:5022)")
}

// runReadParamsDemo 运行读参数演示
func runReadParamsDemo() {
	fmt.Println("\n开始读参数功能演示...")

	// 创建TCP客户端
	provider := gomodbus.NewTCPClientProvider("127.0.0.1:5022", gomodbus.TCPClientTimeout(5*time.Second))
	client := gomodbus.NewClient(provider)

	fmt.Println("\n=== 功能码 0x54: 读子设备参数 ===")
	testReadSubDevParams(client)

	fmt.Println("\n=== 功能码 0x55: 读网关参数 ===")
	testReadGatewayParams(client)

	fmt.Println("\n=== 参数读写综合演示 ===")
	testReadWriteCombo(client)

	fmt.Println("\n=== 演示完成 ===")
}

// testReadSubDevParams 测试读子设备参数
func testReadSubDevParams(client gomodbus.Client) {
	slaveID := byte(1) // 变送器地址

	fmt.Printf("读取变送器 %d 的参数:\n", slaveID)

	// 读取压力单位参数
	value, err := client.GatewayReadSubDevParam(slaveID, gomodbus.SubDevParamPressureUnit)
	if err != nil {
		fmt.Printf("   读取压力单位失败: %v\n", err)
	} else {
		unitName := gomodbus.GetPressureUnitName(uint8(value))
		fmt.Printf("   压力单位: %s (值: %d)\n", unitName, value)
	}

	// 读取数据上报间隔参数
	value, err = client.GatewayReadSubDevParam(slaveID, gomodbus.SubDevParamDataReportInterval)
	if err != nil {
		fmt.Printf("   读取数据上报间隔失败: %v\n", err)
	} else {
		fmt.Printf("   数据上报间隔: %d 秒\n", value)
	}

	// 读取变送器地址参数
	value, err = client.GatewayReadSubDevParam(slaveID, gomodbus.SubDevParamTransmitterAddr)
	if err != nil {
		fmt.Printf("   读取变送器地址失败: %v\n", err)
	} else {
		fmt.Printf("   变送器地址: %d\n", value)
	}

	// 读取液晶显示小数位参数
	value, err = client.GatewayReadSubDevParam(slaveID, gomodbus.SubDevParamLCDDecimalPlaces)
	if err != nil {
		fmt.Printf("   读取液晶显示小数位失败: %v\n", err)
	} else {
		fmt.Printf("   液晶显示小数位: %d\n", value)
	}
}

// testReadGatewayParams 测试读网关参数
func testReadGatewayParams(client gomodbus.Client) {
	slaveID := byte(65) // 网关地址

	fmt.Printf("读取网关 %d 的参数:\n", slaveID)

	// 读取RS485波特率参数
	value, err := client.GatewayReadGatewayParam(slaveID, gomodbus.GatewayParamRS485Baudrate)
	if err != nil {
		fmt.Printf("   读取RS485波特率失败: %v\n", err)
	} else {
		fmt.Printf("   RS485波特率: %d bps\n", value)
	}

	// 读取RS485地址参数
	value, err = client.GatewayReadGatewayParam(slaveID, gomodbus.GatewayParamRS485Address)
	if err != nil {
		fmt.Printf("   读取RS485地址失败: %v\n", err)
	} else {
		fmt.Printf("   RS485地址: %d\n", value)
	}

	// 读取背光显示时间参数
	value, err = client.GatewayReadGatewayParam(slaveID, gomodbus.GatewayParamBacklightTime)
	if err != nil {
		fmt.Printf("   读取背光显示时间失败: %v\n", err)
	} else {
		fmt.Printf("   背光显示时间: %d (0=10秒, 1=30秒, 2=60秒, 3=常亮)\n", value)
	}

	// 读取时间参数
	value, err = client.GatewayReadGatewayParam(slaveID, gomodbus.GatewayParamTime)
	if err != nil {
		fmt.Printf("   读取时间失败: %v\n", err)
	} else {
		timestamp := time.Unix(int64(value), 0)
		fmt.Printf("   时间: %s (Unix时间戳: %d)\n", timestamp.Format("2006-01-02 15:04:05"), value)
	}
}

// testReadWriteCombo 测试参数读写组合操作
func testReadWriteCombo(client gomodbus.Client) {
	fmt.Println("演示参数读写组合操作:")

	// 1. 修改变送器压力单位从 KPa 改为 Bar
	slaveID := byte(1)

	fmt.Println("1. 修改变送器压力单位 KPa -> Bar")

	// 读取当前值
	oldValue, err := client.GatewayReadSubDevParam(slaveID, gomodbus.SubDevParamPressureUnit)
	if err != nil {
		fmt.Printf("   读取当前压力单位失败: %v\n", err)
		return
	}
	fmt.Printf("   当前压力单位: %s\n", gomodbus.GetPressureUnitName(uint8(oldValue)))

	// 修改为 Bar
	err = client.GatewayWriteSubDevParam(slaveID, gomodbus.SubDevParamPressureUnit, gomodbus.PressureUnitBar)
	if err != nil {
		fmt.Printf("   修改压力单位失败: %v\n", err)
		return
	}
	fmt.Printf("   成功修改压力单位为 Bar\n")

	// 再次读取确认
	newValue, err := client.GatewayReadSubDevParam(slaveID, gomodbus.SubDevParamPressureUnit)
	if err != nil {
		fmt.Printf("   读取新的压力单位失败: %v\n", err)
		return
	}
	fmt.Printf("   确认新的压力单位: %s\n", gomodbus.GetPressureUnitName(uint8(newValue)))

	// 2. 修改网关波特率
	gatewayID := byte(65)

	fmt.Println("\n2. 修改网关波特率 115200 -> 9600")

	// 读取当前值
	oldBaudrate, err := client.GatewayReadGatewayParam(gatewayID, gomodbus.GatewayParamRS485Baudrate)
	if err != nil {
		fmt.Printf("   读取当前波特率失败: %v\n", err)
		return
	}
	fmt.Printf("   当前波特率: %d bps\n", oldBaudrate)

	// 修改为 9600
	err = client.GatewayWriteGatewayParam(gatewayID, gomodbus.GatewayParamRS485Baudrate, 9600)
	if err != nil {
		fmt.Printf("   修改波特率失败: %v\n", err)
		return
	}
	fmt.Printf("   成功修改波特率为 9600 bps\n")

	// 再次读取确认
	newBaudrate, err := client.GatewayReadGatewayParam(gatewayID, gomodbus.GatewayParamRS485Baudrate)
	if err != nil {
		fmt.Printf("   读取新的波特率失败: %v\n", err)
		return
	}
	fmt.Printf("   确认新的波特率: %d bps\n", newBaudrate)

	fmt.Println("\n参数读写功能验证完成！")
}
